<?php
/**
 * Created by PhpStorm
 * Author niuyongqiang@kungeek.com
 * Date 2022/2/11 18:16
 */


use App\Services\ErrorCodeService;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator;
use Monolog\Logger;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use zgldh\QiniuStorage\QiniuStorage;
use Monolog\Handler\RotatingFileHandler;


/**
 * 检测参数
 * @param array $rule
 * @param array $message
 * @return JsonResponse|void
 */
if (!function_exists('checkParams')) {
    function checkParams($params = array(), array $rule = array(), array $message = array())
    {
        $validator = Validator::make($params, $rule, $message);
        if ($validator->fails()) {
            return sendError(ErrorCodeService::ERROR_PARAM_NOT_EXIST, $validator->errors()->first());
        }
        return false;
    }
}


/**
 * 统一成功返回
 * @param null $data
 * @param string $msg
 * @param int $status
 */
if (!function_exists('sendSuccess')) {
    function sendSuccess($data = null, string $msg = '', int $status = 200): JsonResponse
    {
        if (empty($msg)) {
            $msg = !empty(ErrorCodeService::getErrorMessage(ErrorCodeService::SUCCESS)) ? ErrorCodeService::getErrorMessage(ErrorCodeService::SUCCESS) : '成功';
        }
        return response()->json([
            'code' => ErrorCodeService::SUCCESS,
            'message' => $msg,
            'data' => empty($data) ? (object)[] : $data
        ], $status);
    }
}

/**
 * 统一失败返回
 * @param array $data
 * @param string $msg
 * @param int $code
 * @param int $status
 */
if (!function_exists('sendError')) {
    function sendError(int $code = ErrorCodeService::ERROR_DEFAULT, string $msg = '', array $data = [], int $status = 200): JsonResponse
    {
        if (empty($msg)) {
            $msg = !empty(ErrorCodeService::getErrorMessage($code)) ? ErrorCodeService::getErrorMessage($code) : '失败';
        }
        return response()->json([
            'code' => $code,
            'message' => $msg,
            'data' => empty($data) ? (object)[] : $data
        ], $status);
    }
}


/**
 * 产生随机字符串，不长于32位
 * @param int $length
 * @return string
 */
if (!function_exists('getNonceStr')) {

    function getNonceStr(int $length = 32): string
    {
        $chars = "#abcdefghilkmnopqrstuvwxyz0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }
}


/** 加密
 * @param $data
 * @return array|string|string[]
 */
if (!function_exists('aesEncrypt')) {
    function aesEncrypt($data)
    {
        return openssl_encrypt($data, 'aes-128-ecb', '1234567891234567');
    }
}


/**
 * 解密
 * @param $data
 * @return string
 */
if (!function_exists('aesDecrypt')) {
    function aesDecrypt($data): string
    {
        return openssl_decrypt($data, 'aes-128-ecb', '1234567891234567');
    }
}

/**
 * 手机号脱敏
 * eg:    $mobile = desensitize($mobile,3,4);
 * @param $data
 * @return string
 */
if (!function_exists('desensitize')) {
    function desensitize($string, $start = 3, $length = 4, $res = '*')
    {
        if (empty($string) || empty($length) || empty($res)) return $string;
        $end = $start + $length;
        $strlen = mb_strlen($string);
        $str_arr = array();
        for ($i = 0; $i < $strlen; $i++) {
            if ($i >= $start && $i < $end)
                $str_arr[] = $res;
            else
                $str_arr[] = mb_substr($string, $i, 1);
        }
        return implode('', $str_arr);
    }
}

/**
 * 把返回的数据集转换成Tree
 * @param array $list 要转换的数据集
 * @param string $pk 自增字段（栏目id）
 * @param string $pid parent标记字段
 * @param string $child parent标记字段
 * @return array
 */
if (!function_exists('makeTree')) {
    function makeTree(array $list, string $pk = 'id', string $pid = 'pid', string $child = '_child', $showChild = true): array
    {

        $items = array();
        foreach ($list as $data) {
            if (is_object($data)) {
                $data = (array)$data;
            }
            $items[$data[$pk]] = $data;
            if ($showChild) {
                $items [$data[$pk]][$child] = [];
            }
        }
        $tree = array();
        foreach ($items as $k => $item) {
            if (isset($items[$item[$pid]])) {
                $items[$item[$pid]][$child][] = &$items[$k];
            } else {
                $tree[] = &$items[$k];
            }
        }
        return $tree;
    }
}

/**
 * 把返回的数据集转换成Tree
 * @param array $list 要转换的数据集
 * @param string $pk 自增字段（栏目id）
 * @param string $pid parent标记字段
 * @param string $child parent标记字段
 * @return array
 */
if (!function_exists('makeTreeByNum')) {
    function makeTreeByNum(array $list, string $pk = 'id', string $pid = 'pid', string $child = '_child', $showChild = true): array
    {

        $items = array();
        foreach ($list as $data) {
            if (is_object($data)) {
                $data = (array)$data;
            }
            $items[$data[$pk]] = $data;
            if ($showChild) {
                $items [$data[$pk]][$child] = [];
            }
        }
        $tree = array();
        foreach ($items as $k => $item) {
            if (isset($items[$item[$pid]])) {
                $items[$item[$pid]][$child][] = &$items[$k];
                $items[$item[$pid]]['num']++;
            } else {
                $tree[] = &$items[$k];
            }
        }
        return $tree;
    }
}

/**
 * 把返回的数据集转换成Tree
 * @param array $list 要转换的数据集
 * @param string $pk 自增字段（栏目id）
 * @param string $pid parent标记字段
 * @param string $child parent标记字段
 * @return array
 */
if (!function_exists('makeTreeLevel')) {
    function makeTreeLevel($array, $pid = 0, $level = 0, $pidName = 'parentid'): array
    {
        //声明静态数组,避免递归调用时,多次声明导致数组覆盖
        static $list = [];
        foreach ($array as $key => $value) {
            //第一次遍历,找到父节点为根节点的节点 也就是pid=0的节点
            if ($value[$pidName] == $pid) {
                //父节点为根节点的节点,级别为0，也就是第一级
                if (!empty($level)) {
                    $value['level'] = $level . ',' . $value['id'];
                } else {
                    $value['level'] = $value['id'];

                }
                //把数组放到list中
                $list[] = $value;
                //把这个节点从数组中移除,减少后续递归消耗
                unset($array[$key]);

                //开始递归,查找父ID为该节点ID的节点,级别则为原级别+1
                makeTreeLevel($array, $value['id'], $value['level'], $pidName);

            }
        }
        return $list;
    }
}


/**
 * 获取登录用户信息
 */
if (!function_exists('adminUserInfo')) {
    /**
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    function adminUserInfo($key = null)
    {
        //获取用户信息
        $session = session()->get('adminUser');

        if (is_null($key)) {
            return $session;
        } else {
            if (empty($session)) return false;
            return Arr::get($session, $key, false);
        }
    }
}

/**
 * 获取登录用户信息
 */
if (!function_exists('adminH5User')) {
    /**
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    function adminH5User($key = null)
    {
        //获取用户信息
        $session = session()->get('adminH5User');

        if (is_null($key)) {
            return $session;
        } else {
            if (empty($session)) return false;
            return Arr::get($session, $key, false);
        }
    }
}

/**
 * 获取登录后台管理的用户信息
 */
if (!function_exists('adminInfo')) {
    /**
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    function adminInfo($key = null)
    {
        //获取用户信息
        $session = session()->get('admin');

        if (is_null($key)) {
            return $session;
        } else {
            if (empty($session)) return false;
            return Arr::get($session, $key, false);
        }
    }
}

/**
 * 获取饲养员登录用户信息
 */
if (!function_exists('adminBreederInfo')) {
    /**
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    function adminBreederInfo($key = null)
    {
        //获取用户信息
        $session = session()->get('adminBreederInfo');

        if (is_null($key)) {
            return $session;
        } else {
            if (empty($session)) return false;
            return Arr::get($session, $key, false);
        }
    }
}

/**
 * 打印
 */
if (!function_exists('D')) {
    function D($temp = null)
    {
        if ($temp === null) {
            $temp = $_REQUEST;
        }

        if (isset($GLOBALS['start_start'])) {
            $t2 = microtime(true);
            echo '耗时' . round($t2 - $GLOBALS['start_start'], 3) . '秒';
        }

        echo '<pre> <b><div style="overflow: auto; border:2px black dashed; font-family:微软雅黑,serif; background-color:#FFE4C4; color:#DC143C">测试数据:<br><hr><p>';
        print_r($temp);
        echo '</p><hr></div></b>';
        die;
    }
}


/**
 * 记录日志
 * @param $file_name
 * @param $tag
 * @param $content
 */
function writeLoToFile($file_name, $tag, $content)
{
    $log_file = 'logs/' . date("Ymd") . "/" . $file_name . '.log';
//    D([php_sapi_name() , 'fpm-fcgi']);
    if (php_sapi_name() == 'fpm-fcgi') {
        $log_file = 'logs/' . date("Ymd") . "/" . $file_name . '.log';
    } else {
        $log_file = 'logs/cron/' . date("Ymd") . "/" . $file_name . '.log';
    }
    if (is_array($content)) {
        $content = json_encode($content, JSON_UNESCAPED_UNICODE);
    }
    (new Logger($tag))->pushHandler(new RotatingFileHandler(storage_path($log_file)))->info($content);
}

function handleInt($number){
    return intval($number * 100) / 100;
}

if (!function_exists('logWriter')) {
    /**
     * 日志编写器
     * @param string $name
     * @param string $log
     */
    function logWriter(string $name, string $log)
    {
        (new Logger($name))->pushHandler(new RotatingFileHandler(storage_path("logs/$name.log")))->info($log);
    }
}
/**
 * 判断文件大小
 */
if (!function_exists('sizeCount')) {
    function sizeCount($filesize)
    {
        if ($filesize >= 1073741824) {
            $filesize = intval($filesize / 1073741824) . ' GB';
        } elseif ($filesize >= 1048576) {
            $filesize = intval($filesize / 1048576) . ' MB';
        } elseif ($filesize >= 1024) {
            $filesize = intval($filesize / 1024) . ' KB';
        }
        return $filesize;
    }
}

if (!function_exists('downloadWechatImg')) {
    /**
     * 保存微信头像
     * @param string $localPath
     * @param $wechatPath
     * @param string $filename
     * @return string
     */
    function downloadWechatImg(string $localPath = '/common/', $wechatPath, string $filename = ''): string
    {

        // mime 和 扩展名 的映射
        $mimes = array(
            'image/bmp' => 'bmp',
            'image/gif' => 'gif',
            'image/jpeg' => 'jpg',
            'image/png' => 'png',
            'image/x-icon' => 'ico'
        );
        if ($wechatPath == '' || $wechatPath == null) {
            return '';
        }
        $headers = get_headers($wechatPath, 1);
        if (!isset($mimes[$headers['Content-Type']])) {
            exit('未知媒体类型');
        }
        $ext = $mimes[$headers['Content-Type']];

        //下载图片资源
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_URL, $wechatPath);
        ob_start();
        curl_exec($ch);
        $return_content = ob_get_contents();
        ob_end_clean();

        if ($filename) {
            $filename = md5($filename) . '.' . $ext;
        } else {
            $filename = date('Y-m-d-h-i-s') . mt_rand(10000, 99999) . '.' . $ext;

        }
        // Storage::disk('public')->put($filename, $return_content);

        //上传七牛云
        $disk = QiniuStorage::disk('qiniu');
        config('filesystems.disks.qiniu');
        $bool = $disk->put($localPath . $filename, $return_content);
        if ($bool) {
            return $localPath . $filename;
        }
        return '';
    }
}

/**
 * 循环遍历，将数组里的下划线都变成单驼峰
 * @param $arr
 * @return mixed
 */
if (!function_exists('arrToUcFirst')) {
    function arrToUcFirst($arr): array
    {
        $newA = [];
        foreach ($arr as $k => $v) {
            $k = strToUcFirst($k);
            if (is_array($v)) {
                $v = arrToUcFirst($v);
            }

            $newA[$k] = $v;
            unset($arr[$k]);
        }
        return $newA;
    }
}

/**
 * 字符串变成单驼峰
 * @param $k
 * @param bool $ucfirst false 单驼峰，true 双驼峰
 * @return mixed|string
 */
if (!function_exists('strToUcFirst')) {
    function strToUcFirst($k, $ucfirst = false)
    {
        if (($pos = strpos($k, '_')) !== false) {
            $k = ucwords(str_replace('_', ' ', $k));
            $k = str_replace(' ', '', lcfirst($k));
            $k = $ucfirst ? ucfirst($k) : $k;
        }
        return $k;
    }
}


/**
 * 发送http 请求
 */
if (!function_exists('httpUtil')) {
    function httpUtil($url, string $data = '', string $method = 'GET', array $headers = [])
    {
        try {
            $curl = curl_init(); // 启动一个CURL会话
            if (!empty($headers)) {
                curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
            }
            curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
            curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
            curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
            if ($method == 'POST') {
                curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
                if ($data != '') {
                    curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的数据包
                }
            }
            curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
            curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
            $tmpInfo = curl_exec($curl); // 执行操作
            curl_close($curl); // 关闭CURL会话
            return $tmpInfo; // 返回数据
        } catch (Exception $e) {
            die($e->getMessage());
        }
    }

}

/**
 * xml 转 数组
 * @param $xml
 * @return mixed
 */
if (!function_exists('xmlToArray')) {
    function xmlToArray($xml)
    {
        $obj = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
        $json = json_encode($obj);
        return json_decode($json, true);
    }
}


if (!function_exists('url_safe_base64_encode')) {
    function url_safe_base64_encode($data)
    {
        return str_replace(array('+', '/', '='), array('-', '_', ''), base64_encode($data));
    }
}

if (!function_exists('url_safe_base64_decode')) {
    function url_safe_base64_decode($data)
    {
        $base_64 = str_replace(array('-', '_'), array('+', '/'), $data);
        return base64_decode($base_64);
    }
}

/**
 * curl https请求
 * @param $url
 * @param $data
 * @param array $header
 * @return array
 */
if (!function_exists('curl_https')) {
    function curl_https($url, $data, array $header = array())
    {
        try {
            writeLoToFile('http-url', $url, $data);
            writeLoToFile('http-url', $url, $header);
            $header = $header ?? array("Content-type:application/x-www-form-urlencode");
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);  // 从证书中检查SSL加密算法是否存在
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, 30);
            $response = curl_exec($ch);
            curl_close($ch);
            return [
                'success' => true,
                'data' => json_decode($response, true),
            ];
        } catch (Exception $e) {
            $errorCode = $e->getCode();
            $errorMessage = $e->getMessage();

            return [
                'success' => false,
                'errorCode' => $errorCode,
                'errorMessage' => json_encode($errorMessage),
            ];
        }

    }
}

if (!function_exists('contrastAnalysis')) {
    /**
     * 环比分析
     * @return string
     */
    function contrastAnalysis($now = array(), $contrast = array(), $filed = '')
    {
        if (!$filed) {
            return '对比字段不能为空！';
        }
        if (empty($now) || empty($contrast)) {
            return '--';
        }

        if ($contrast[$filed] > 0) {
            return (string)round(($now[$filed] - $contrast[$filed]) / $contrast[$filed] * 100, 2) . '%';
        }
        return '0.00%';

    }
}

if (!function_exists('getFirstChart')) {
    /**
     * 返回取汉字的第一个字的首字母
     * @param  [type] $str [string]
     * @return [type]      [strind]
     */
    function getFirstChart($str){
        if( empty($str) ){
            return '';
        }
        $char=ord($str[0]);
        if( $char >= ord('A') && $char <= ord('z') ){
            return strtoupper($str[0]);
        }
        $s1=iconv('UTF-8','gb2312',$str);
        $s2=iconv('gb2312','UTF-8',$s1);
        $s=$s2==$str?$s1:$str;

        if (!isset($s[1])) {
            return '';
        }

        $asc=ord($s[0])*256+ord($s[1])-65536;

        if($asc>=-20319&&$asc<=-20284) return 'A';
        if($asc>=-20283&&$asc<=-19776) return 'B';
        if($asc>=-19775&&$asc<=-19219) return 'C';
        if($asc>=-19218&&$asc<=-18711) return 'D';
        if($asc>=-18710&&$asc<=-18527) return 'E';
        if($asc>=-18526&&$asc<=-18240) return 'F';
        if($asc>=-18239&&$asc<=-17923) return 'G';
        if($asc>=-17922&&$asc<=-17418) return 'H';
        if($asc>=-17417&&$asc<=-16475) return 'J';
        if($asc>=-16474&&$asc<=-16213) return 'K';
        if($asc>=-16212&&$asc<=-15641) return 'L';
        if($asc>=-15640&&$asc<=-15166) return 'M';
        if($asc>=-15165&&$asc<=-14923) return 'N';
        if($asc>=-14922&&$asc<=-14915) return 'O';
        if($asc>=-14914&&$asc<=-14631) return 'P';
        if($asc>=-14630&&$asc<=-14150) return 'Q';
        if($asc>=-14149&&$asc<=-14091) return 'R';
        if($asc>=-14090&&$asc<=-13319) return 'S';
        if($asc>=-13318&&$asc<=-12839) return 'T';
        if($asc>=-12838&&$asc<=-12557) return 'W';
        if($asc>=-12556&&$asc<=-11848) return 'X';
        if($asc>=-11847&&$asc<=-11056) return 'Y';
        if($asc>=-11055&&$asc<=-10247) return 'Z';
        return '';
    }

}

if (!function_exists('getMillisecond')) {
    function getMillisecond() {
        list($t1, $t2) = explode(' ', microtime());
        return (float)sprintf('%.0f',(floatval($t1)+floatval($t2))*1000);
    }
}


/**
 * 秒数转化天 时 分
 * @param $seconds
 * @return mixed|string
 */
if (!function_exists('timeToSecond')) {
    function timeToSecond($seconds)
    {
        $seconds = (int)$seconds;
        if ($seconds < 86400) {//如果不到一天
            $format_time = gmstrftime('%H时%M分%S秒', $seconds);
        } else {
            $time = explode(' ', gmstrftime('%j %H %M %S', $seconds));//Array ( [0] => 04 [1] => 14 [2] => 14 [3] => 35 )
            $format_time = ($time[0] - 1) . '天' . $time[1] . '时' . $time[2] . '分' . $time[3] . '秒';
        }
        return $format_time;
    }
}




